package com.test.mapper.services.impl;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.test.dao.SearchCriteria;
import com.test.dao.SearchResultSet;
import com.test.mapper.dao.EntityPropertyDao;
import com.test.mapper.enitites.EntityModel;
import com.test.mapper.enitites.EntityProperty;
import com.test.mapper.services.EntityPropertyService;
import com.test.utils.dao.DBUtils;
import com.test.utils.search.SearchUtils;

public class EntityPropertyServiceImpl implements EntityPropertyService {

	private Logger logger;

	private EntityPropertyDao entityPropertyDao;

	public boolean addProperty(final EntityProperty property) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean editProperty(final EntityProperty property) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean removeProperty(final EntityProperty property) {
		// TODO Auto-generated method stub
		return false;
	}

	public EntityProperty getPropertyByColumnName(final int clientId, final	String tableName,
			final String columnName)
	{
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see com.test.mapper.services.EntityPropertyService#searchForProperties(com.test.dao.SearchCriteria)
	 */
	public SearchResultSet<EntityProperty> searchForProperties(final SearchCriteria criteria) {

		logger.debug("START searchForProperties");

		final Collection<EntityProperty> resultList = entityPropertyDao.search(criteria.getProperties());
		final SearchResultSet<EntityProperty> resultSet = new SearchResultSet<EntityProperty>();
		resultSet.setTotalResultSize(resultList.size());
		final SearchUtils.SearchResultIndex indexes = SearchUtils.calculateIndexes(
				resultList.size(), criteria.getPageNumber(), criteria.getItemsPerPage());
		if (resultList.size() == 0 || criteria.getItemsPerPage() <= 0 || criteria.getPageNumber() <= 0
				|| indexes.getStartIndex() < 0 || indexes.getEndIndex() < 0) {
			resultSet.setResultList(resultList);
		} else {
			if (indexes.getEndIndex() + 1 == resultSet.getTotalResultSize()) {
				resultSet.setResultList(new ArrayList<EntityProperty>(resultList).subList(indexes.getStartIndex(), resultList.size()));
			} else {
				resultSet.setResultList(new ArrayList<EntityProperty>(resultList).subList(indexes.getStartIndex(), indexes.getEndIndex()));
			}
		}
		// populate foreign keys and models
		for (EntityProperty ep : resultSet.getResultList()) {
			if (ep.getForeignModel() != null && StringUtils.isNotBlank(ep.getForeignModel().getTableName())) {
				
			}
			if (ep.getForeignKeyTo() != null && StringUtils.isNotBlank(ep.getForeignKeyTo().getColumnName())) {
				
			}
		}

		logger.debug("END searchForProperties");

		return resultSet;
	}

	/*
	 * (non-Javadoc)
	 * @see com.test.mapper.services.EntityPropertyService#generateColumnName(com.test.mapper.enitites.EntityProperty)
	 */
	public void generateColumnName(final EntityProperty property) {
		if (property == null) {
			throw new NullPointerException("Property is null");
		}
		if (StringUtils.isBlank(property.getPropertyName())) {
			throw new IllegalArgumentException("Property name cannot be empty");
		}
		property.setColumnName(DBUtils.generateDBIdentifierFromName(property.getPropertyName()));
	}

	/*
	 * (non-Javadoc)
	 * @see com.test.mapper.services.EntityPropertyService#loadPropertiesForEntity(com.test.mapper.enitites.EntityModel)
	 */
	public void loadPropertiesForEntity(final EntityModel entity) {
		logger.debug("START loadPropertiesForEntity");

		if (entity == null) {
			throw new NullPointerException("Cannot load properties for NULL entity");
		}
		if (entity.getClientId() == null || entity.getClientId() <= 0
				|| StringUtils.isBlank(entity.getTableName())) {
			throw new IllegalArgumentException("Client ID and table name must be set and valid");
		}
		final SearchCriteria criteria = new SearchCriteria();
		criteria.addPropertyCriteria("clientId", entity.getClientId());
		criteria.addPropertyCriteria("tableName", entity.getTableName());
		final SearchResultSet<EntityProperty> resultSet = searchForProperties(criteria);

		logger.debug("Search result: " + resultSet.getOpResult());

		entity.setProperties(resultSet.getResultList());

		logger.debug("END loadPropertiesForEntity");
	}

	public Logger getLogger() {
		return logger;
	}

	public void setLogger(Logger logger) {
		this.logger = logger;
	}

	public EntityPropertyDao getEntityPropertyDao() {
		return entityPropertyDao;
	}

	public void setEntityPropertyDao(EntityPropertyDao entityPropertyDao) {
		this.entityPropertyDao = entityPropertyDao;
	}
}
